Ava Pythoni 'email' paketi potentsiaal. Ăpi looma keerulisi MIME-sĂ”numeid ja parsima sissetulevaid e-kirju andmete efektiivseks ja globaalseks ekstraktsiooniks.
Pythoni 'email' paketi valdamine: MIME-sÔnumite loomise ja usaldusvÀÀrse parsimise kunst
E-post on jĂ€tkuvalt globaalse suhtluse nurgakivi, asendamatu isiklikuks kirjavahetuseks, Ă€ritegevuseks ja automatiseeritud sĂŒsteemiteatisteks. Iga rikkaliku tekstiga e-kirja, iga manuse ja iga hoolikalt vormindatud allkirja taga peitub Multipurpose Internet Mail Extensions (MIME) keerukus. Arendajate jaoks, eriti nende jaoks, kes töötavad Pythoniga, on nende MIME-sĂ”numite programmeerimise teel loomise ja parsimise valdamine kriitilise tĂ€htsusega oskus.
Pythoni sisseehitatud pakett email
pakub tugeva ja pĂ”hjaliku raamistiku e-kirjade kĂ€sitlemiseks. See ei ole ainult lihtsa teksti saatmiseks; see on loodud MIME-i keeruliste detailide abstraheerimiseks, vĂ”imaldades teil luua keerulisi e-kirju ja eraldada sissetulevatest sĂ”numitest spetsiifilisi andmeid mĂ€rkimisvÀÀrse tĂ€psusega. See juhend viib teid sĂŒvitsi selle paketi kahe peamise tahuga: MIME-sĂ”numite loomine saatmiseks ja nende parsimine andmete ekstraheerimiseks, pakkudes globaalset vaatenurka parimatele tavadele.
Nii loomise kui ka parsimise mĂ”istmine on ĂŒlioluline. SĂ”numit luues mÀÀratlete sisuliselt selle struktuuri ja sisu, et teine sĂŒsteem saaks seda tĂ”lgendada. Parsides tĂ”lgendate teise sĂŒsteemi mÀÀratletud struktuuri ja sisu. Ăhe sĂŒgav mĂ”istmine aitab oluliselt kaasa teise valdamisele, mis viib vastupidavamate ja koostalitlusvĂ”imelisemate e-posti rakendusteni.
MIME mÔistmine: kaasaegse e-posti selgroog
Enne Pythoni spetsiifikasse sĂŒvenemist on oluline mĂ”ista, mis on MIME ja miks see nii elutĂ€htis on. Algselt piirdusid e-kirjad lihttekstiga (7-bitised ASCII-mĂ€rgid). MIME, mis vĂ”eti kasutusele 1990. aastate alguses, laiendas e-posti vĂ”imalusi toetama:
- Mitte-ASCII mÀrgid: VÔimaldades teksti keeltes nagu araabia, hiina, vene vÔi mis tahes muus keeles, mis kasutab mÀrke vÀljaspool ASCII kompletti.
- Manused: Failide (nt dokumendid, pildid, heli ja video) saatmine.
- Rikas tekstivorming: HTML-kirjad paksus kirjas, kursiivkirjas, vÀrvide ja paigutustega.
- Mitu osa: Lihtteksti, HTML-i ja manuste kombineerimine ĂŒhes e-kirjas.
MIME saavutab selle, lisades e-kirjale spetsiifilised pÀised ja struktureerides selle sisu erinevateks "osadeks". Peamised MIME-pÀised, millega kokku puutute, hÔlmavad:
Content-Type:
MÀÀrab osa andmetĂŒĂŒbi (nttext/plain
,text/html
,image/jpeg
,application/pdf
,multipart/alternative
). See sisaldab sageli ka parameetritcharset
(ntcharset=utf-8
).Content-Transfer-Encoding:
NĂ€itab, kuidas e-posti klient peaks sisu dekodeerima (ntbase64
binaarandmete puhul,quoted-printable
peamiselt teksti puhul koos mÔnede mitte-ASCII mÀrkidega).Content-Disposition:
Soovitab, kuidas saaja e-posti klient peaks osa kuvama (ntinline
kuvamiseks sÔnumi kehas,attachment
salvestatava faili jaoks).
Pythoni pakett email
: sĂŒvaanalĂŒĂŒs
Pythoni pakett email
on pĂ”hjalik teek, mis on loodud e-kirjade programmeerimise teel loomiseks, parsimiseks ja muutmiseks. See on ĂŒles ehitatud Message
objektide kontseptsioonile, mis esindavad e-kirja struktuuri.
Paketi vÔtmemoodulid hÔlmavad:
email.message:
Sisaldab pÔhilist klassiEmailMessage
, mis on peamine liides e-kirjade loomiseks ja manipuleerimiseks. See on vÀga paindlik klass, mis kÀsitleb MIME-i detaile automaatselt.email.mime:
Pakub pÀrandklasse (naguMIMEText
,MIMEMultipart
), mis pakuvad MIME-struktuurile selgemat kontrolli. KuigiEmailMessage
on lihtsuse tĂ”ttu uue koodi jaoks ĂŒldiselt eelistatud, vĂ”ib nende klasside mĂ”istmine olla kasulik.email.parser:
Pakub klasse naguBytesParser
jaParser
toore e-posti andmete (baitide vÔi stringide) teisendamiseksEmailMessage
objektideks.email.policy:
MÀÀrab poliitikad, mis kontrollivad e-kirjade loomise ja parsimise viisi, mÔjutades pÀise kodeeringut, reavahetusi ja veakÀsitlust.
Enamiku tÀnapÀevaste kasutusjuhtude puhul suhtlete peamiselt klassiga email.message.EmailMessage
nii loomiseks kui ka parsimise tulemusena saadud sÔnumiobjekti jaoks. Selle meetodid lihtsustavad oluliselt protsessi, mis oli pÀrandklassidega email.mime
varem palju mahukam.
MIME-sÔnumi loomine: e-kirjade koostamine tÀpsusega
E-kirjade koostamine hÔlmab erinevate komponentide (tekst, HTML, manused) kokkupanemist kehtivaks MIME-struktuuriks. Klass EmailMessage
lihtsustab seda protsessi mÀrkimisvÀÀrselt.
PÔhilised tekstilised e-kirjad
Lihtsaim e-kiri on lihttekst. Saate sellise luua ja pÔhilised pÀised vaevata seadistada:
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'Tervitused Pythonist'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('Tere, see on lihtteksti e-kiri, mis on saadetud Pythonist.\n\nParimate soovidega,\nTeie Pythoni Skript')
print(msg.as_string())
Selgitus:
EmailMessage()
loob tĂŒhja sĂ”numiobjekti.- SĂ”nastiku-laadne ligipÀÀs (
msg['Subject'] = ...
) seab tavalised pÀised. set_content()
lisab e-kirja pÔhilise sisu. Vaikimisi jÀreldab seeContent-Type: text/plain; charset="utf-8"
.as_string()
serialiseerib sÔnumi stringvormingusse, mis sobib saatmiseks SMTP kaudu vÔi salvestamiseks faili.
HTML-sisu lisamine
HTML-e-kirja saatmiseks mÀÀrate lihtsalt sisutĂŒĂŒbi, kui kutsute vĂ€lja set_content()
. Hea tava on pakkuda lihtteksti alternatiivi vastuvÔtjatele, kelle e-posti kliendid HTML-i ei renderda, vÔi ligipÀÀsetavuse pÔhjustel.
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'Teie HTML-uudiskiri'
msg['From'] = 'newsletter@example.com'
msg['To'] = 'subscriber@example.com'
html_content = """
<html>
<head></head>
<body>
<h1>Tere tulemast meie globaalsesse uuendusse!</h1>
<p>Hea tellija,</p>
<p>See on teie <strong>viimane uuendus</strong> kogu maailmast.</p>
<p>Lisateabe saamiseks kĂŒlastage meie <a href="http://www.example.com">veebisaiti</a>.</p>
<p>Parimate soovidega,<br>Meeskond</p>
</body>
</html>
"""
# Add the HTML version
msg.add_alternative(html_content, subtype='html')
# Add a plain text fallback
plain_text_content = (
"Tere tulemast meie globaalsesse uuendusse!\n\n"
"Hea tellija,\n\n"
"See on teie viimane uuendus kogu maailmast.\n"
"KĂŒlastage meie veebisaiti lisateabe saamiseks: http://www.example.com\n\n"
"Parimate soovidega,\nThe Team"
)
msg.add_alternative(plain_text_content, subtype='plain')
print(msg.as_string())
Selgitus:
add_alternative()
kasutatakse *sama* sisu erinevate esituste lisamiseks. E-posti klient kuvab "parima", mida see suudab kÀsitleda (tavaliselt HTML).- See loob automaatselt
multipart/alternative
MIME-struktuuri.
Manuste kÀsitlemine
Failide lisamine on lihtne, kasutades add_attachment()
. Saate lisada mis tahes tĂŒĂŒpi faile ja pakett kĂ€sitleb sobivaid MIME-tĂŒĂŒpe ja kodeeringuid (tavaliselt base64
).
from email.message import EmailMessage
from pathlib import Path
# Create dummy files for demonstration
Path('report.pdf').write_bytes(b'%PDF-1.4\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj\n2 0 obj<</Count 0>>endobj\nxref\n0 3\n0000000000 65535 f\n0000000009 00000 n\n0000000052 00000 n\ntrailer<</Size 3/Root 1 0 R>>startxref\n104\n%%EOF') # VÀga lihtne, kehtetu PDF-kohatÀide
Path('logo.png').write_bytes(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0cIDAT\x08\x99c`\x00\x00\x00\x02\x00\x01\xe2!\x00\xa0\x00\x00\x00\x00IEND\xaeB`\x82') # 1x1 lÀbipaistev PNG-kohatÀide
msg = EmailMessage()
msg['Subject'] = 'Oluline dokument ja pilt'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('Palun leiate lisatud aruande ja ettevÔtte logo.')
# Attach a PDF file
with open('report.pdf', 'rb') as f:
file_data = f.read()
msg.add_attachment(
file_data,
maintype='application',
subtype='pdf',
filename='Aastaaruanne_2024.pdf'
)
# Attach an image file
with open('logo.png', 'rb') as f:
image_data = f.read()
msg.add_attachment(
image_data,
maintype='image',
subtype='png',
filename='EttevÔtteLogo.png'
)
print(msg.as_string())
# Clean up dummy files
Path('report.pdf').unlink()
Path('logo.png').unlink()
Selgitus:
add_attachment()
vÔtab vastu faili sisu toorbaidid.maintype
jasubtype
mÀÀravad MIME-tĂŒĂŒbi (ntapplication/pdf
,image/png
). Need on vastuvĂ”tja e-posti kliendi jaoks ĂŒliolulised manuse Ă”igeks tuvastamiseks ja kĂ€sitlemiseks.filename
annab nime, mille all vastuvÔtja manuse salvestab.- See seadistab automaatselt
multipart/mixed
struktuuri.
Mitmeosaliste sÔnumite loomine
Kui teil on sÔnum, mis sisaldab nii HTML-keha, lihtteksti varuvarianti kui ka sisemisi pilte vÔi seotud faile, vajate keerukamat mitmeosaline struktuuri. Klass EmailMessage
kÀsitleb seda arukalt meetoditega add_related()
ja add_alternative()
.
Levinud stsenaarium on HTML-e-kiri koos otse HTML-i sisse manustatud pildiga (nn "inline" pilt). See kasutab multipart/related
.
from email.message import EmailMessage
from pathlib import Path
# Create a dummy image file for demonstration (a 1x1 transparent PNG)
Path('banner.png').write_bytes(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0cIDAT\x08\x99c`\x00\x00\x00\x02\x00\x01\xe2!\x00\xa0\x00\x00\x00\x00IEND\xaeB`\x82')
msg = EmailMessage()
msg['Subject'] = 'Sisepildi nÀide'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
# Plain text version (fallback)
plain_text = 'Vaadake meie suurepĂ€rast bannerit!\n\n[Pilt: Banner.png]\n\nKĂŒlastage meie saiti.'
msg.set_content(plain_text, subtype='plain') # Seadistage esialgne lihtteksti sisu
# HTML version (with CID for inline image)
html_content = """
<html>
<head></head>
<body>
<h1>Meie uusim pakkumine!</h1>
<p>Hea klient,</p>
<p>Ărge jĂ€tke kasutamata meie erilist globaalset pakkumist:</p>
<img src="cid:my-banner-image" alt="Kampaania banner">
<p>Lisateabe saamiseks klÔpsake <a href="http://www.example.com">siin</a>.</p>
</body>
</html>
"""
msg.add_alternative(html_content, subtype='html') # Lisage HTML-alternatiiv
# Add the inline image (related content)
with open('banner.png', 'rb') as img_file:
image_data = img_file.read()
msg.add_related(
image_data,
maintype='image',
subtype='png',
cid='my-banner-image' # See CID vastab HTML-i 'src' atribuudile
)
print(msg.as_string())
# Clean up dummy file
Path('banner.png').unlink()
Selgitus:
set_content()
loob algse sisu (siin lihttekst).add_alternative()
lisab HTML-versiooni, luuesmultipart/alternative
struktuuri, mis sisaldab lihtteksti ja HTML-i osi.add_related()
kasutatakse sisu jaoks, mis on "seotud" ĂŒhe sĂ”numi osaga, tavaliselt sisemiste piltidega HTML-is. See vĂ”tab vastucid
(Content-ID) parameetri, millele seejÀrel viidatakse HTML-i<img src="cid:my-banner-image">
sildis.- LÔplik struktuur on
multipart/mixed
(kui oli vÀliseid manuseid), mis sisaldabmultipart/alternative
osa, mis omakorda sisaldabmultipart/related
osa.multipart/related
osa sisaldab HTML-i ja sisemist pilti. KlassEmailMessage
kÀsitleb seda pesastamise keerukust teie eest.
Kodeering ja mÀrgistikud globaalseks haardeks
Rahvusvahelise suhtluse jaoks on Ă”ige mĂ€rgifkodeering ĂŒlitĂ€htis. Pakett email
eelistab vaikimisi tugevalt UTF-8 kasutamist, mis on universaalne standard erinevate mÀrgifkodeeringute kÀsitlemiseks kogu maailmast.
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = 'Globaalsed mĂ€rgid: ăăă«ăĄăŻ, ĐŃĐžĐČĐ”Ń, à€šà€źà€žà„à€€à„'
msg['From'] = 'global_sender@example.com'
msg['To'] = 'global_recipient@example.com'
# Japanese, Russian, and Hindi characters
content = "See sÔnum sisaldab erinevaid globaalseid mÀrke:\n"
content += "ăăă«ăĄăŻ (jaapani)\n"
content += "ĐŃĐžĐČĐ”Ń (vene)\n"
content += "à€šà€źà€žà„à€€à„ (hindi)\n\n"
content += "Pakett 'email' kÀsitleb UTF-8 graatsiliselt."
msg.set_content(content)
print(msg.as_string())
Selgitus:
- Kui
set_content()
saab Pythoni stringi, kodeerib see selle automaatselt UTF-8-ks ja seab pÀiseContent-Type: text/plain; charset="utf-8"
. - Kui sisu seda nÔuab (nt sisaldab palju mitte-ASCII mÀrke), vÔib see rakendada ka
Content-Transfer-Encoding: quoted-printable
vÔibase64
, et tagada turvaline edastus vanemate e-posti sĂŒsteemide kaudu. Pakett kĂ€sitleb seda automaatselt vastavalt valitud poliitikale.
Kohandatud pÀised ja poliitikad
Saate e-kirjale lisada mis tahes kohandatud pÀise. Poliitikad (moodulist email.policy
) mÀÀravad, kuidas sĂ”numeid kĂ€sitletakse, mĂ”jutades selliseid aspekte nagu pĂ€ise kodeering, reavahetused ja veakĂ€sitlus. VaikekĂ€itumine on ĂŒldiselt hea, kuid saate valida `SMTP` rangeks SMTP vastavuseks vĂ”i mÀÀratleda kohandatud poliitikad.
from email.message import EmailMessage
from email import policy
msg = EmailMessage(policy=policy.SMTP)
msg['Subject'] = 'E-kiri kohandatud pÀisega'
msg['From'] = 'info@example.org'
msg['To'] = 'user@example.org'
msg['X-Custom-Header'] = 'See on kohandatud vÀÀrtus jÀlgimiseks'
msg['Reply-To'] = 'support@example.org'
msg.set_content('See e-kiri demonstreerib kohandatud pÀiseid ja poliitikaid.')
print(msg.as_string())
Selgitus:
- Kasutades
policy=policy.SMTP
tagatakse range vastavus SMTP standarditele, mis vÔib olla kohaletoimetatavuse seisukohalt kriitiline. - Kohandatud pÀised lisatakse samamoodi nagu standardsed. Need algavad sageli
X-
-ga, et tÀhistada mittestandardseid pÀiseid.
MIME-sÔnumite parsimine: teabe ekstraheerimine sissetulevatest e-kirjadest
Parsimine hÔlmab toore e-posti andmete (tavaliselt saadud IMAP-i kaudu vÔi failist) vÔtmist ja nende teisendamist `EmailMessage` objektiks, mida saate seejÀrel hÔlpsasti uurida ja manipuleerida.
Laadimine ja esialgne parsimine
Tavaliselt saate e-kirju toorbaididena. Selleks kasutatakse email.parser.BytesParser
(vÔi abifunktsioone email.message_from_bytes()
).
from email.parser import BytesParser
from email.policy import default
raw_email_bytes = b"""
From: sender@example.com
To: recipient@example.com
Subject: Test Email with Basic Headers
Date: Mon, 1 Jan 2024 10:00:00 +0000
Content-Type: text/plain; charset="utf-8"
See on e-kirja sisu.
See on lihtne test.
"""
# Using BytesParser
parser = BytesParser(policy=default)
msg = parser.parsebytes(raw_email_bytes)
# Or using the convenience function
# from email import message_from_bytes
# msg = message_from_bytes(raw_email_bytes, policy=default)
print(f"Subject: {msg['subject']}")
print(f"From: {msg['from']}")
print(f"Content-Type: {msg['Content-Type']}")
Selgitus:
BytesParser
vÔtab vastu toored baidandmed (nii edastatakse e-kirju) ja tagastabEmailMessage
objekti.policy=default
mÀÀrab parsimisreeglid.
PĂ€iste avamine
PÀised on hÔlpsasti ligipÀÀsetavad sÔnastiku-laadsete vÔtmete kaudu. Pakett kÀsitleb automaatselt kodeeritud pÀiste (nt rahvusvaheliste mÀrkedega teemade) dekodeerimist.
# ... (kasutades eelmisest parsimise nÀitest saadud 'msg' objekti)
print(f"KuupÀev: {msg['date']}")
print(f"SÔnumi ID: {msg['Message-ID'] if 'Message-ID' in msg else 'N/A'}")
# Mitu pÀist kÀsitlemine (nt 'Received' pÀised)
# from email.message import EmailMessage # Kui pole veel imporditud
# from email import message_from_string # Kiire stringi nÀite jaoks
multi_header_email = message_from_string(
"""
From: a@example.com
To: b@example.com
Subject: Mitme pÀise test
Received: from client.example.com (client.example.com [192.168.1.100])
by server.example.com (Postfix) with ESMTP id 123456789
for <b@example.com>; Mon, 1 Jan 2024 10:00:00 +0000 (GMT)
Received: from mx.another.com (mx.another.com [192.168.1.101])
by server.example.com (Postfix) with ESMTP id 987654321
for <b@example.com>; Mon, 1 Jan 2024 09:59:00 +0000 (GMT)
Sisu on siin.
"""
)
received_headers = multi_header_email.get_all('received')
if received_headers:
print("\nSaadud pÀised:")
for header in received_headers:
print(f"- {header}")
Selgitus:
- PÀisele ligipÀÀs tagastab selle vÀÀrtuse stringina.
get_all('header-name')
on kasulik pÀiste jaoks, mis vÔivad esineda mitu korda (naguReceived
).- Pakett kÀsitleb pÀiste dekodeerimist, nii et vÀÀrtused nagu
Subject: =?utf-8?Q?Global_Characters:_=E3=81=93=E3=82=93=E3=81=AB=E3=81=A1=E3=81=AF?=
teisendatakse automaatselt loetavateks stringideks.
Sisu ekstraheerimine
Tegeliku sÔnumi sisu ekstraheerimine nÔuab kontrollimist, kas sÔnum on mitmeosaline. Mitmeosaliste sÔnumite puhul itereeritakse selle osi.
from email.message import EmailMessage
from email import message_from_string
multipart_email_raw = """
From: multi@example.com
To: user@example.com
Subject: Mitmeosaline e-posti test
Content-Type: multipart/alternative; boundary="_----------=_12345"
--_----------=_12345
Content-Type: text/plain; charset="utf-8"
Tervitused lihtteksti osast!
--_----------=_12345
Content-Type: text/html; charset="utf-8"
<html>
<body>
<h1>Tervitused HTML-osast!</h1>
<p>See on <strong>rikas tekstiga</strong> e-kiri.</p>
</body>
</html>
--_----------=_12345--
"""
msg = message_from_string(multipart_email_raw)
if msg.is_multipart():
print("\n--- Mitmeosaline e-kirja sisu ---")
for part in msg.iter_parts():
content_type = part.get_content_type()
charset = part.get_content_charset() or 'utf-8' # VaikevÀÀrtus utf-8, kui pole mÀÀratud
payload = part.get_payload(decode=True) # Dekodeerige sisu baidid
try:
decoded_content = payload.decode(charset)
print(f"Content-Type: {content_type}, Charset: {charset}\nContent:\n{decoded_content}\n")
except UnicodeDecodeError:
print(f"Content-Type: {content_type}, Charset: {charset}\nContent: (Binaarsed vÔi dekodeerimatud andmed)\n")
# KÀsitlege binaarseid andmeid vÔi proovige varukodeeringut
else:
print("\n--- Ăheosaline e-kirja sisu ---")
charset = msg.get_content_charset() or 'utf-8'
payload = msg.get_payload(decode=True)
try:
decoded_content = payload.decode(charset)
print(f"Content-Type: {msg.get_content_type()}, Charset: {charset}\nContent:\n{decoded_content}\n")
except UnicodeDecodeError:
print(f"Content: (Binaarsed vÔi dekodeerimatud andmed)\n")
Selgitus:
is_multipart()
mÀÀrab, kas e-kirjal on mitu osa.iter_parts()
itereerib lÀbi mitmeosalise sÔnumi kÔigi alam-osade.get_content_type()
tagastab tĂ€ieliku MIME-tĂŒĂŒbi (nttext/plain
).get_content_charset()
eraldab mĂ€rgitĂŒĂŒbiContent-Type
pÀisest.get_payload(decode=True)
on ĂŒlioluline: see tagastab *dekodeeritud* sisu baitidena. SeejĂ€rel peate need baidid.decode()
abil Ă”ige mĂ€rgitĂŒĂŒbi jĂ€rgi dekodeerima, et saada Pythoni string.
Manuste kÀsitlemine parsimise kÀigus
Manused on samuti osa mitmeosalisest sÔnumist. Saate need tuvastada nende Content-Disposition
pÀise abil ja salvestada nende dekodeeritud sisu.
from email.message import EmailMessage
from email import message_from_string
import os
# Example email with a simple attachment
email_with_attachment = """
From: attach@example.com
To: user@example.com
Subject: Dokument lisatud
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="_----------=_XYZ"
--_----------=_XYZ
Content-Type: text/plain; charset="utf-8"
Siin on teie soovitud dokument.
--_----------=_XYZ
Content-Type: application/pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="document.pdf"
JVBERi0xLjQKMSAwIG9iagpbL1BERi9UZXh0L0ltYWdlQy9JbWFnZUkvSW1hZ0VCXQplbmRvYmoK
--_----------=_XYZ--
"""
msg = message_from_string(email_with_attachment)
output_dir = 'parsed_attachments'
os.makedirs(output_dir, exist_ok=True)
print("\n--- Manuste töötlemine ---")
for part in msg.iter_attachments():
filename = part.get_filename()
if filename:
filepath = os.path.join(output_dir, filename)
try:
with open(filepath, 'wb') as f:
f.write(part.get_payload(decode=True))
print(f"Salvestati manus: {filepath} (TĂŒĂŒp: {part.get_content_type()})")
except Exception as e:
print(f"Viga {filename} salvestamisel: {e}")
else:
print(f"Leiti manus ilma failinimeta (Content-Type: {part.get_content_type()})")
# Clean up the output directory
# import shutil
# shutil.rmtree(output_dir)
Selgitus:
iter_attachments()
annab konkreetselt osad, mis on tÔenÀoliselt manused (st neil onContent-Disposition: attachment
pÀis vÔi neid pole muul viisil klassifitseeritud).get_filename()
eraldab failinimeContent-Disposition
pÀisest.part.get_payload(decode=True)
toob manuse toore binaarse sisu, mis on juba dekodeeritudbase64
-st vÔiquoted-printable
-st.
Kodeeringute ja mÀrgistikute dekodeerimine
Pakett email
teeb suurepÀrast tööd, dekodeerides automaatselt tavalisi edastuskodeeringuid (nagu base64
, quoted-printable
), kui kutsute vÀlja get_payload(decode=True)
. Tekstisisu puhul proovib see kasutada Content-Type
pÀises mÀÀratud charset
. Kui mĂ€rgitĂŒĂŒpi pole mÀÀratud vĂ”i see on kehtetu, peate seda vĂ”ib-olla graatsiliselt kĂ€sitlema.
from email.message import EmailMessage
from email import message_from_string
# Example with a potentially problematic charset
email_latin1 = """
From: legacy@example.com
To: new_system@example.com
Subject: ErinĂ”uded: Ă Ă©ĂĂłĂș
Content-Type: text/plain; charset="iso-8859-1"
See sĂ”num sisaldab Latin-1 mĂ€rke: Ă Ă©ĂĂłĂș
"""
msg = message_from_string(email_latin1)
if msg.is_multipart():
for part in msg.iter_parts():
payload = part.get_payload(decode=True)
charset = part.get_content_charset() or 'utf-8'
try:
print(f"Dekodeeritud (mÀrgistik: {charset}): {payload.decode(charset)}")
except UnicodeDecodeError:
print(f"Dekodeerimine nurjus mÀrgistikuga {charset}. Proovitakse varuvarianti...")
# Varuvariandina tavaline mÀrgistik vÔi 'latin-1', kui seda oodatakse
print(f"Dekodeeritud (varuvariandi Latin-1): {payload.decode('latin-1', errors='replace')}")
else:
payload = msg.get_payload(decode=True)
charset = msg.get_content_charset() or 'utf-8'
try:
print(f"Dekodeeritud (mÀrgistik: {charset}): {payload.decode(charset)}")
except UnicodeDecodeError:
print(f"Dekodeerimine nurjus mÀrgistikuga {charset}. Proovitakse varuvarianti...")
print(f"Dekodeeritud (varuvariandi Latin-1): {payload.decode('latin-1', errors='replace')}")
Selgitus:
- Proovige alati kasutada
Content-Type
pÀises mÀÀratud mÀrgistikku. - Kasutage
try-except UnicodeDecodeError
plokki vastupidavuse tagamiseks, eriti kui tegemist on erinevate ja potentsiaalselt mittestandardsete allikate e-kirjadega. errors='replace'
vÔierrors='ignore'
saab kasutada koos.decode()
-ga, et kÀsitleda mÀrke, mida ei saa sihtkodeeringuga kaardistada, vÀltides seega kokkujooksmist.
TĂ€psemad parsimisstsenaariumid
PÀrismaailma e-kirjad vÔivad olla vÀga keerulised, sisaldades pesastatud mitmeosalisi struktuure. Paketi email
rekursiivne olemus teeb nende navigeerimise lihtsaks. Saate kombineerida is_multipart()
ja iter_parts()
, et lĂ€bida sĂŒgavalt pesastatud sĂ”numeid.
from email.message import EmailMessage
from email import message_from_string
def parse_email_part(part, indent=0):
prefix = " " * indent
content_type = part.get_content_type()
charset = part.get_content_charset() or 'N/A'
print(f"{prefix}Osa tĂŒĂŒp: {content_type}, MĂ€rgistik: {charset}")
if part.is_multipart():
for subpart in part.iter_parts():
parse_email_part(subpart, indent + 1)
elif part.get_filename(): # See on manus
print(f"{prefix} Manus: {part.get_filename()} (Suurus: {len(part.get_payload(decode=True))} baiti)")
else: # See on tavaline tekst/html sisu osa
payload = part.get_payload(decode=True)
try:
decoded_content = payload.decode(charset)
# print(f"{prefix} Sisu (esimesed 100 mĂ€rki): {decoded_content[:100]}...") # LĂŒhiduse huvides
except UnicodeDecodeError:
print(f"{prefix} Sisu: (Binaarne vÔi dekodeerimatu tekst)")
complex_email_raw = """
From: complex@example.com
To: receiver@example.com
Subject: Keeruline e-kiri HTML-i, lihtteksti ja manusega
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="outer_boundary"
--outer_boundary
Content-Type: multipart/alternative; boundary="inner_boundary"
--inner_boundary
Content-Type: text/plain; charset="utf-8"
Lihtteksti sisu.
--inner_boundary
Content-Type: text/html; charset="utf-8"
<html><body><h2>HTML sisu</h2></body></html>
--inner_boundary--
--outer_boundary
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="data.bin"
SGVsbG8gV29ybGQh
--outer_boundary--
"""
msg = message_from_string(complex_email_raw)
print("\n--- Keerulise e-kirja struktuuri lÀbimine ---")
parse_email_part(msg)
Selgitus:
- Rekursiivne funktsioon
parse_email_part
demonstreerib, kuidas lĂ€bida kogu sĂ”numipuu, tuvastades mitmeosalised osad, manused ja kehasisu igal tasandil. - See muster on vĂ€ga paindlik konkreetsete sisutĂŒĂŒpide ekstraheerimiseks sĂŒgavalt pesastatud e-kirjadest.
Loomine vs. Parsimine: vÔrdlev vaatenurk
Kuigi need on eraldiseisvad toimingud, on loomine ja parsimine sama mĂŒndi kaks kĂŒlge: MIME-sĂ”numite kĂ€sitlemine. Ăhe mĂ”istmine aitab paratamatult teise mĂ”istmisel kaasa.
Loomine (saatmine):
- Fookus: PÀiste, sisu ja manuste Ôige kokkupanemine standarditele vastavaks MIME-struktuuriks.
- Peamine tööriist:
email.message.EmailMessage
koos meetoditega naguset_content()
,add_attachment()
,add_alternative()
,add_related()
. - Peamised vĂ€ljakutsed: Ăigete MIME-tĂŒĂŒpide, mĂ€rgistikute (eriti UTF-8 globaalse toe jaoks), `Content-Transfer-Encoding` ja Ă”ige pĂ€isevormingu tagamine. Vead vĂ”ivad viia e-kirjade valesti kuvamiseni, manuste riknemiseni vĂ”i sĂ”numite rĂ€mpspostiks mĂ€rkimiseni.
Parsimine (vastuvÔtmine):
- Fookus: Toore e-kirja baidivoo lahtivÔtmine selle koostisosadeks, spetsiifiliste pÀiste, sisu ja manuste ekstraheerimine.
- Peamine tööriist:
email.parser.BytesParser
vÔiemail.message_from_bytes()
, seejÀrel navigeerimine saadudEmailMessage
objektiga, kasutades meetodeid naguis_multipart()
,iter_parts()
,get_payload()
,get_filename()
ja pÀistele ligipÀÀs. - Peamised vÀljakutsed: Valesti vormistatud e-kirjade kÀsitlemine, mÀrgifkodeeringute Ôige tuvastamine (eriti kui need on ebaselged), puuduvate pÀistega tegelemine ja andmete robustne ekstraheerimine erinevatest MIME-struktuuridest.
SĂ”num, mille te konstrueerite kasutades `EmailMessage`, peaks olema `BytesParser` poolt tĂ€iuslikult parsitav. Samamoodi annab parsimise kĂ€igus toodetud MIME-struktuuri mĂ”istmine teile ĂŒlevaate, kuidas ise keerulisi sĂ”numeid ehitada.
Parimad praktikad globaalse e-posti kÀsitlemiseks Pythoniga
Rakenduste puhul, mis suhtlevad globaalse publikuga vÔi kÀsitlevad erinevaid e-posti allikaid, kaaluge jÀrgmisi parimaid tavasid:
- Standardiseeri UTF-8-le: Kasutage alati UTF-8-t kogu tekstisisu jaoks, nii loomisel kui ka parsimise kÀigus oodates. See on globaalne standard mÀrgifkodeeringu jaoks ja vÀldib mojibake'i (moonutatud tekst).
- Valideeri e-posti aadresse: Enne saatmist valideerige vastuvÔtja e-posti aadressid, et tagada kohaletoimetatavus. Parsimise kÀigus olge valmis potentsiaalselt kehtetute vÔi valesti vormistatud aadresside jaoks pÀistes `From`, `To` vÔi `Cc`.
- Testige rangelt: Testige oma e-kirjade loomist erinevate e-posti klientidega (Gmail, Outlook, Apple Mail, Thunderbird) ja platvormidega, et tagada HTML-i ja manuste jÀrjepidev renderdamine. Parsimiseks testige laia valiku nÀidiskirjadega, sealhulgas nendega, millel on ebatavalised kodeeringud, puuduvad pÀised vÔi keerulised pesastatud struktuurid.
- Puhasta parsimisel sisend: Kohelge sissetulevatest e-kirjadest ekstraheeritud sisu alati ebausaldusvÀÀrsena. Puhastage HTML-sisu, et vĂ€ltida XSS-rĂŒnnakuid, kui kuvate seda veebirakenduses. Valideerige manuste failinimed ja tĂŒĂŒbid, et vĂ€ltida kataloogi lĂ€bimist vĂ”i muid turvaauke failide salvestamisel.
- Tugev veakÀsitlus: Rakendage pÔhjalikke
try-except
plokke sisu dekodeerimisel vÔi potentsiaalselt puuduvatele pÀistele ligipÀÀsemisel. KÀsitlege graatsiliseltUnicodeDecodeError
vÔiKeyError
. - KĂ€sitle suuri manuseid: Olge teadlik manuste suurusest, nii loomisel (et vĂ€ltida meiliserveri piirangute ĂŒletamist) kui ka parsimisel (et vĂ€ltida liigset mĂ€lu- vĂ”i kettaruumi tarbimist). Kaaluge suurte manuste voogesitust, kui teie sĂŒsteem seda toetab.
- Kasuta
email.policy
: Kriitiliste rakenduste puhul valige selgelt `email.policy` (nt `policy.SMTP`), et tagada range vastavus e-posti standarditele, mis vĂ”ib mĂ”jutada kohaletoimetatavust ja koostalitlusvĂ”imet. - Metainfo sĂ€ilitamine: Parsimisel otsustage, millist metainfot (pĂ€iseid, algseid piiride stringe) on oluline sĂ€ilitada, eriti kui ehitate e-posti arhiveerimis- vĂ”i edastussĂŒsteemi.
JĂ€reldus
Pythoni pakett email
on uskumatult vĂ”imas ja paindlik teek kĂ”igile, kes vajavad e-kirjadega programmeerimise teel suhtlemist. Valdades nii MIME-sĂ”numite loomist kui ka sissetulevate e-kirjade robustset parsimist, avate vĂ”imaluse luua keerulisi e-posti automatiseerimissĂŒsteeme, ehitada e-posti kliente, analĂŒĂŒsida e-posti andmeid ja integreerida e-posti funktsionaalsusi praktiliselt igasse rakendusse.
Pakett kĂ€sitleb lĂ€bimĂ”eldult MIME-i alusstruktuuri keerukust, vĂ”imaldades arendajatel keskenduda oma e-posti interaktsioonide sisule ja loogikale. Olenemata sellest, kas saadate isikupĂ€rastatud uudiskirju globaalsele publikule vĂ”i ekstraheerite kriitilisi andmeid automatiseeritud sĂŒsteemi aruannetest, osutub paketi email
sĂŒgav mĂ”istmine hindamatuks usaldusvÀÀrsete, koostalitlusvĂ”imeliste ja globaalselt teadlike e-posti lahenduste loomisel.